﻿using System.Collections.Generic;

namespace System.Linq
{
    /// <summary>
    /// distinct 方法
    /// </summary>
    public static class DistinctExtention
    {
        /// <summary>
        /// 按照属性来做distinct,默认comparer
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TKet"></typeparam>
        /// <param name="source"></param>
        /// <param name="keySelector"></param>
        /// <returns></returns>
        public static IEnumerable<T> Distinct<T, TKet>(this IEnumerable<T> source, Func<T, TKet> keySelector)
        {
            return source.Distinct(new CommonEqualityComparer<T, TKet>(keySelector));
        }
        /// <summary>
        /// 按照属性来做distinct,自定义comparer
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="source"></param>
        /// <param name="keySelector"></param>
        /// <param name="comparer"></param>
        /// <returns></returns>
        public static IEnumerable<T> Distinct<T, TKey>(this IEnumerable<T> source, Func<T, TKey> keySelector, IEqualityComparer<TKey> comparer)
        {
            return source.Distinct(new CommonEqualityComparer<T, TKey>(keySelector, comparer));
        }
    }

    class CommonEqualityComparer<T, TKey> : IEqualityComparer<T>
    {
        private readonly Func<T, TKey> keySelector;
        private readonly IEqualityComparer<TKey> comparer;

        public CommonEqualityComparer(Func<T, TKey> keySelector, IEqualityComparer<TKey> comparer)
        {
            this.keySelector = keySelector;
            this.comparer = comparer;
        }

        public CommonEqualityComparer(Func<T, TKey> keySelector)
            : this(keySelector, EqualityComparer<TKey>.Default)
        { }

        public bool Equals(T x, T y)
        {
            return comparer.Equals(keySelector(x), keySelector(y));
        }

        public int GetHashCode(T obj)
        {
            return comparer.GetHashCode(keySelector(obj));
        }
    }
}
